#include"string.h"

Mystring::string::string(const char* str)
:_size(strlen(str))
,_capacity(_size)
,_str(new char[_size+1])
{
    cout<<"string()"<<endl;
    memcpy(_str,str,_size+1);
}

Mystring::string& Mystring::string::operator=(const string&s)
{
    cout<<"operator="<<endl;
    char* tmp=new char[s._capacity+1];
    memcpy(tmp,s._str,s._size+1);
    delete[] _str;
    _str=tmp;
    _capacity=s._capacity;
    _size=s._size;
    return *this;
}

 Mystring::string::~string()
 {
    cout<<"~string()"<<endl;
    delete[] _str;
    _str=nullptr;
    _size=0;
    _capacity=0;
}

Mystring::string::string(const string&s)
{
    cout<<"string()"<<endl;
    _str=new char[s._capacity+1];
    strcpy(_str,s._str);
    _size=s._size;
    _capacity=s._capacity;
}


void Mystring::string::reserve(size_t n)
{
    if(n>_capacity){
        char*tmp=new char[n+1];
        memcpy(tmp,_str,_size+1);
        delete[] _str;
        _str=tmp;
        _capacity=n;
    }
}

void Mystring::string::resize(size_t n,char ch)
{
    if(n>_capacity){
        reserve(n);
    }
    if(n>_size){
        for(size_t i=_size;i<n;i++){
            _str[i]=ch;
        }
    }
    _size=n;
    _str[_size]='\0';

}

void Mystring::string::push_back(char ch)
{
    if(_size==_capacity){
        reserve(_capacity==0?4:2*_capacity);
    }
    _str[_size]=ch;
    _size++;
    _str[_size]='\0';
}

void Mystring::string::append(char ch)
{
    push_back(ch);
}

void Mystring::string::append(const char* str)
{
    size_t len=strlen(str);
    if(_size+len>_capacity){
        reserve(_size+len);
    }
    memcpy(_str+_size,str,len+1);
    _size+=len;
}

Mystring::string& Mystring::string::operator+=(char ch)
{
    push_back(ch);
    return *this;
}

Mystring::string& Mystring::string::operator+=(const char* str)
{
   append(str);
    return *this;
}

size_t Mystring::string::find(char ch,size_t pos)
{
    assert(pos<_size);
    for(size_t i=pos;i<_size;i++){
        if(_str[i]==ch){
            return i;
        }
    }
    return npos;
}

size_t Mystring::string::find(const char*str,size_t pos)
{
    assert(pos<_size);
    const char* ptr=strstr(_str+pos,str);
    if(ptr){
        return ptr-_str;
    }
    else{
        return npos;
    }
}

void Mystring::string::insert(size_t pos,size_t n,char ch)
{
    assert(pos<_size);
    if((_size+n)>_capacity){
        reserve(_size+n);
    }
    size_t end=_size;
    while(end>=pos&&end!=npos){
        _str[end+n]=_str[end];
        end--;
    }
    for(size_t i=0;i<n;i++){
        _str[pos+i]=ch;
    }
    _size+=n;

}

void Mystring::string::insert(size_t pos,const char*str)
{
    assert(pos<_size);
    size_t len=strlen(str);
    if(_size+len>_capacity){
        reserve(_size+len);
    }
    size_t end=_size;
    while(end>=pos&&end!=npos){
        _str[end+len]=_str[end];
        end--;
    }
    for(size_t i=0;i<len;i++){
        _str[pos+i]=str[i];
    }
    _size+=len;
}

void Mystring::string::erase(size_t pos,size_t len)
{
    assert(pos<_size);
    if(len==npos||pos+len>=_size){
        _size=pos;
        _str[_size]='\0';
    }
    else{
        size_t end=len+pos;
        while(end<=_size){
            _str[pos++]=_str[end++];
        }
        _size-=len;
    }
}

ostream& Mystring::operator<<(ostream& out,const string&s)
{
    cout<<"operator<<"<<endl;
    for(auto e:s){
        out<<e;
    }
    return out;
}

istream& Mystring::operator>>(istream &in, string &s)
{
    cout<<"operator>>"<<endl;
    s.clear();
    char ch = in.get();
	// 处理前缓冲区前面的空格或者换行
	while (ch == ' ' || ch == '\n')
	{
		ch = in.get();
	}
	char buff[128];
	int i = 0;
	while (ch != ' ' && ch != '\n')
	{
		buff[i++] = ch;
		if (i == 127)
		{
			buff[i] = '\0';
			s += buff;
			i = 0;
		}
		ch = in.get();
	}
	if (i != 0)
	{
		buff[i] = '\0';
		s += buff;
	}
	return in;
}